<template>
  <div
    id="container"
    ref="containerRef"
    style="width: 100%; height: 100%"
  ></div>
  <el-dialog v-model="orgVisible" title=" " width="60%" append-to-body>
    <p class="title_1 mb10">{{ orgName }}</p>
    <p class="title_2 mb10">查看统计数据</p>
    <div class="ml20">
      <el-button type="primary" plain>单节点(包含分支机构)</el-button>
      <el-button type="primary" plain>单节点</el-button>
      <el-button type="primary" plain>多节点含下级企业</el-button>
      <el-button type="primary" plain>查看客户视图</el-button>
      <el-button type="primary" plain>客户信息修改</el-button>
    </div>
  </el-dialog>
</template>

<script setup>
/**
 * G6-缩进树组件
 * 组件的宽高需要在父元素调用套一个div并设置宽高
 * 该组件只是demo，实际业务要treeData改成props；
 * orgTags字段是用来展示企业的标识icon的
*/
import G6 from "@antv/g6";
import expand from "@/assets/icons/svg/add.svg";
import collapse from "@/assets/icons/svg/minus.svg";
import tag_1 from "@/assets/icons/svg/tag_1.svg";
import tag_2 from "@/assets/icons/svg/tag_2.svg";
import tag_3 from "@/assets/icons/svg/tag_3.svg";
import tag_8 from "@/assets/icons/svg/tag_8.svg";
import tag_10 from "@/assets/icons/svg/tag_11.svg";
import { ref } from "vue";
const colors = {
  tag_4: '#fce3b4',
  tag_5: '#b7d883',
  tag_6: '#c8e2fc',
  tag_7: '#cec8ef',
  tag_9: '#ed3934',
}
const containerRef = ref(null);

// 点击公司节点逻辑
const orgVisible = ref(false)
const orgName = ref("")
function clickOrg(item){
  orgVisible.value = true
  orgName.value = item.label
}

// 递归处理treeData业务数据
function addColorAttribute(item) {
  if(item.orgTags){
    item.icons = []
    item.orgTags.split(',').forEach(tag => {
      item = setTag(tag, item)
    })
  }
  if (item.children) {
    item.children.forEach(child => {
      addColorAttribute(child); // 递归调用
    });
  }
}
// 根据tagCode设置样式
function setTag(code, item){
  switch (code){
    case '1':
      item.icons.push(tag_1)
      break
    case '2':
      item.icons.push(tag_2)
      break
    case '3':
      item.icons.push(tag_3)
      break
    case '4':
      item.backgroundColor = colors.tag_4
      break
    case '5':
      item.backgroundColor = colors.tag_5
      break
    case '6':
      item.backgroundColor = colors.tag_6
      break
    case '7':
      item.backgroundColor = colors.tag_7
      break
    case '8':
      item.icons.push(tag_8)
      break
    case '9':
      item.borderColor = colors.tag_9
      break
    case '10':
      item.icons.push(tag_10)
      break
  }
  return item
}
const treeData = {
  id: "1",
  label: "苏州市人民政府国有资产监管理委员会",
  orgTags: "1,8,4,9", // 实际业务要根据后端返回的orgTags给每个节点item设置对应的borderColor、backgroundColor、icons
  children: [
    {
      id: "1-1",
      label: "苏州市轨道交通集团有限公司",
      orgTags: "1,3,5,9",
      children: [
        {
          id: "1-1-1",
          label: "苏州市轨道交通二号线有限公司",
          orgTags: "1,6,10",
        },
        {
          id: "1-1-2",
          label: "苏州市轨道交通三号线有限公司",
          orgTags: "1,7,8",
        },
        {
          id: "1-1-3",
          label: "苏州市轨道交通四号线有限公司",
          orgTags: "1,4,10",
          children: [
            {
              id: "1-1-1-1",
              label: "苏州市轨道交通八号线有限公司",
              orgTags: "1,6,10",
            },
          ]
        },
      ],
    },
    {
      id: "1-2",
      label: "上海市轨道交通集团有限公司",
      orgTags: "1,5,9",
      children: [
        {
          id: "1-2-1",
          label: "上海市轨道交通二号线有限公司",
          orgTags: "1,6,9",
        },
        {
          id: "1-2-2",
          label: "上海市轨道交通三号线有限公司",
          orgTags: "1,7,9",
        },
      ],
    },
    {
      id: "1-3",
      label: "上海市轨道交通四号线有限公司",
      orgTags: "1,2,4,9",
    },
    {
      id: "1-4",
      label: "上海市轨道交通九号线有限公司",
      orgTags: "1,2,5,9",
      children: [
        {
          id: "1-4-1",
          label: "上海市轨道交通九号线松江区有限公司",
          orgTags: "1,2,6,9",
        },
      ],
    },
  ],
}
addColorAttribute(treeData);

function initTree() {
  // 注册自定义节点
  G6.registerNode(
    "tree-node",
    {
      drawShape: function drawShape(cfg, group) {
        // 节点-盒子
        const rect = group.addShape("rect", {
          attrs: {
            fill: cfg.backgroundColor || '#e6e5e5', // 节点背景色
            stroke: cfg.borderColor, // 边框颜色
            lineWidth: 1, // 边框粗细
            radius: 2,
            cursor: 'pointer'
          },
          name: "cust-rect-shape",
        });
        // 节点-文本
        const text = group.addShape("text", {
          attrs: {
            text: cfg.label,
            fontFamily: "PingFangSC-Regular",
            fontSize: 12,
            fontWeight: 500,
            textAlign: "center",
            textBaseline: "middle",
            cursor: 'pointer',
            fill: "#333",
          },
          name: "cust-text-shape",
        });
        const bbox = text.getBBox(); // 获得文本的盒子 之后的两个节点的xy轴坐标参考bbox
        // 设置 rect方框和text文本 的 x y坐标轴
        rect.attr({
          x: -bbox.width / 2 - 5,
          y: -bbox.height,
          width: bbox.width + 10,
          height: bbox.height + 8,
        });
        const minbbox = rect.getBBox();
        // 节点旁边的icon
        if (cfg.icons && cfg.icons.length) {
          cfg.icons.forEach((tagIcon, tagIndx) => {
            group.addShape("image", {
              attrs: {
                img: tagIcon,
                width: 18,
                height: 18,
                x: minbbox.width / 2 + tagIndx*18 + 2,
                y: -11
              },
              name: "tag-icon-"+tagIndx,
            });
          })
        }
        const hasChildren = cfg.children && cfg.children.length > 0;
        // 展开收起-icon
        if (hasChildren) {
          const collapseIcon = group.addShape("image", {
            attrs: {
              img: cfg.collapsed ? expand : collapse,
              cursor: "pointer",
              width: 14,
              height: 14,
              x: -7,
              y: 9
            },
            name: "collapse-icon",
          });
          // 展开和收起icon中间是透明的所以加一个白色图层
          group.addShape("rect", {
            attrs: {
              fill: "#fff",
              width: 14,
              height: 14,
              radius: 7,
              x: -7,
              y: 9
            },
            name: "rect-shape2",
          });
          collapseIcon.toFront() // 让collapseIcon处于白色图层上方
        }
        return rect;
      },
      // update: undefined
    },
  );
  // 注册自定义连线
  G6.registerEdge(
    "step-line",
    {
      getControlPoints: function getControlPoints(cfg) {
        const startPoint = cfg.startPoint;
        const endPoint = cfg.endPoint;
        return [
          startPoint,
          {
            x: startPoint.x,
            y: endPoint.y,
          },
          endPoint,
        ];
      },
    },
    "polyline"
  );
  //   注册自定义事件
  G6.registerBehavior("click-node", {
    getEvents() {
      return {
        "node:click": "onNodeClick",
        "canvas:click": "onCanvasClick",
      };
    },
    onNodeClick(e) {
      const { item, target } = e;
      const shape = target;
      const shapeName = shape.cfg.name;
      const model = item.getModel();
      // 点击收起/展开 icon
      if (shapeName === "collapse-icon") {
        const updatedCollapsed = !model.collapsed;
        this.graph.updateItem(item, { collapsed: updatedCollapsed });
        this.graph.layout();
        return;
      }
      if(['cust-rect-shape','cust-text-shape'].includes(shapeName)){
        clickOrg(model)
      }
      // 选中节点
      this.graph.getNodes().forEach((node) => {
        this.graph.setItemState(node, "selected", false);
      });
      this.graph.setItemState(item, "selected", true);
      return;
    },
    // 点击canvas空白处
    onCanvasClick(e) {
      this.graph.getNodes().forEach((node) => {
        this.graph.setItemState(node, "selected", false);
      });
    },
  });
  const graph = new G6.TreeGraph({
    container: containerRef.value,
    width: containerRef.value.offsetWidth,
    height: containerRef.value.offsetHeight,
    fitView: true,
    fitViewPadding: 10,
    fitCenter: true,
    minZoom: 0.1,
    maxZoom: 4,
    modes: {
      default: ["click-node", "drag-canvas", "zoom-canvas"],
    },
    defaultNode: {
      type: "tree-node",
      anchorPoints: [ // 锚点线条的链接点
        [0.5, 1],
        [0.5, 0.5],
      ],
    },
    // 设置边的参数
    defaultEdge: {
      type: "step-line",
      style: {
        stroke: "#78a8c6",
        radius: 6,
      },
    },
    layout: {
      type: "indented",
      direction: "LR",
      isHorizontal: true,
      indent: 150,
      getHeight: () => {
        return 20;
      },
      getVGap: function getVGap() {
        return 10;
      },
    },
  });

  graph.data(treeData);
  graph.render();
  graph.fitView();

  if (typeof window !== "undefined")
    window.onresize = () => {
      if (!graph || graph.get("destroyed")) return;
      if (!containerRef.value || !containerRef.value.scrollWidth || !containerRef.value.scrollHeight)
        return;
      graph.changeSize(containerRef.value.scrollWidth, containerRef.value.scrollHeight);
    };
}
nextTick(() => {
  initTree();
});
</script>